Introduction
In this session we will learn how to perform pathway enrichment
analysis using gene sets from our transcriptomics experiment also termed
as Gene-Set Enrichment Analysis (or GSEA). We will use
two Cytoscape plugins - ClueGO and CluePedia which are the most highly
rated or top download tools in the (cytoscape App store.).

System Requirements:
- Windows, Linux, Unix or MacOS operating system.
- 16 GB RAM recommended. Hard disk with at least 100 MB free (for
example files).
- Java 1.8+ needed - VERY ESSENTIAL.
- Cytoscape 3.7.+ installed: https://cytoscape.org/ -
latest is version 3.10.1.
NOTE: At the first startup, the ClueGO Configuration
folder containing pre-compiled ClueGO files and sample files will be
created in the user home folder. If this folder is removed or the
content damaged, it will be recreated automatically at the next
startup.
License
ClueGO and CluePedia is available
free of charge only to academic, government, and other nonprofit
institutions for noncommercial, nonprofit internal research
purposes.
Note
This course is intended for an audience who which to analyse
biological data (with an example of RNA-Seq) and have no previous
programming experience. However, for those who want to integrate
Cytoscape (and packages like ClueGO and CluePedia) using R or Python,
then please refer to http://www.ici.upmc.fr/cluego/cluegoDocumentation.shtml
to obtain the required API.
Documentation
Generally, the biological interpretation of large gene clusters
derived from high-throughput experiments is a real challenge. Many
ontology sources exist in order to capture biological information in a
meaningful way.
The Gene Ontology (GO) projects [1] aims to capture
the increasing knowledge on gene function in a controlled vocabulary
applicable to all the organisms. GO describes gene products in terms of
their associated biological processes, cellular components and molecular
functions.
Between the terms there is a hierarchical relationship
(parent-child). Due to the complexity of hierarchy structure (directed
acyclic graph), the terms can be in several different levels. The
specificity of the terms varies along the tree: from very general terms
(in first levels of GO) to very specific ones.
Kyoto Encyclopedia of Genes and Genomes (KEGG) [2]
is a database of biological systems that integrates genomic, chemical
and systemic functional information.
(BioCarta) provides
usefull pathway information.
For a complete view on the studied process, several ontology sources
should be consulted in order to integrate their complementary
information. In each source, for each gene, there is a large amount of
information. This makes the analysis of the relationship between genes
and between terms very difficult to represent and comprehend. Also, for
close related terms, a high degree of redundancy of their associated
genes exists.
ClueGO, an open-source Java tool that extracts the
non-redundant biological information for large clusters of genes, using
GO, KEGG and BioCarta. ClueGO is integrated in
Cytoscape (https://cytoscape.org/) as a plug-in and it is taking
advantage of its complex visualization environment.
ClueGO features include:
- ClueGO allows analysis of a single gene set (cluster) or cluster
comparison.
- Different filter criteria can be applied to the terms.
- Fusion of the related terms that have similar associated genes.
- Functional grouping of the terms based on GO hierarchy or based on
kappa score.
- Visualize the selected terms in a functionally grouped network.
- Charts presenting the specific terms and groups for the clusters
compared.
- Statistical significance for the terms and for the groups.
- ClueGO can be used in combination with GOlorize.
- Easy updatable.
- Easy extendable.
Selection Panel
After starting Cytoscape, ClueGO can be found under
the Plugins menu. Once selected, it will display the ClueGO selection
panel options. See Figure below:
- Select the type of analysis. Besides analysis of a single gene set
(cluster), ClueGO performs comparison of clusters, underlying the
specificity and also the common aspects of their functionality.

- Select organism. For the moment, ClueGO supports Arabidopsis
thaliana, Bos taurus, Caenorhabditis elegans, Danio rerio, Dictyostelium
discoideum, Drosophila melanogaster, Escherichia coli, Galus galus, Homo
sapiens, Magnaporthe grisea, Mus musculus, Oryza sativa, Rattus
norvegicus, Saccharomyces cerevisiae.
- Select identifiers type (AffymetrixID, AccessionID, SymbolID).
- The identifiers can be uploaded from text files or interactively
from a Cytoscape sub-network. ClueGO provides sample files containing
specific genes (AccessionID) for Human B and NK cells. A Saccaromyces
network sample (galFiltered.cys) can be found in the Cytoscape
sampleData folder.
- Choose the file with identifiers.
- Select the ontology/ontologies. To make ClueGO faster, we use
precompiled files based on GO, KEGG and BioCarta. The precompiled files
are included in the ClueGOPlugin.jar.
- Select the evidence code, option available for the GO based files.
For more details, see http://www.geneontology.org/GO.evidence.shtml.
- Update the ontology (see ClueGO updates)
- The significance of each term or group can be calculated with
hypergeometric test (enrichment, depletion). Standard is hypergeometric
test two sided.
- Several methods for PValue correction are proposed: Bonferroni,
Bonferroni step-down and BenjaminiHochberg.
- Advanced statistical options
- Select network type. We predefined selection criteria leading to a
”Global” network, a ”Medium” network or a ”Detailed” network. The
”Global” network displays GO terms found in the GO levels 1-3, with a
high number of genes associated and a small percentage of uploaded genes
found. Those terms provide a general biological information. At the
opposite, the ”Detailed” network shows very specific terms placed in GO
levels 9-14, with only few associated genes but a high percentage of the
uploaded genes found. Those terms are more specific and informative
underlying particular aspects of the studied gene product. The
predefined settings provided by ClueGO should be combined with a
customized selection for an analysis adapted to the biological question
addressed (general/specific investigation) and to the number of genes
involved.
- Advanced settings.
- Start the analysis.
ClueGO result
A functionally grouped annotation network, a ClueGO information
table, charts with terms and groups and the loging information are the
result of ClueGO analysis. The created networks and analysis results can
be saved in a specified project folder and used for further analysis. If
the analysis is not needed anymore, it is recommended to close the
project.

Functionally Grouped Annotation Network
ClueGO visualizes the selected terms in a functionally grouped
annotation network (See Figure 2) that reflects the relationships
between the terms based on the similarity of their associated genes. The
size of the nodes reflects the statistical significance of the terms.
The degree of connectivity between terms (edges) is calculated using
kappa statistics, in a similar way as described in [4]. The calculated
kappa score is also used for defining functional groups. A term can be
included in several groups. The reocurrence of the term is shown by
adding ” n”. The not grouped terms are shown in white color. Predefined,
the group leading term is the most significant term of the group. The
network integrates only the positive kappa score term associations and
is automatically laid out using Organic layout algorithm supported by
Cytoscape.
Histogram with terms
The chart presents the specific terms for the user genes and
information related to their associated genes. The display can be
customized (see Advanced settings). Predefined, the bars represent the
number of the genes from the analyzed cluster found associated with the
term, and the label displayed on the bars is the percentage of found
genes compared to all the genes associated with the term. Term
significance information is included in the chart (see Statistics).

Overview Chart with functional groups
The overview chart presents functional groups for the user genes. The
name of the group is given by the group leading term (e.g. the most
significant term in the group). The group sections correlate with the
number of the terms included in group. The position of the sections can
be changed (right click).
Advanced Settings
ClueGO advanced settings allows a precise adjustment of the selection
criteria.

GO tree level. The identifiers can be mapped in the entire
ontology tree or in a GO level interval (between Min and Max levels). If
selected the first GO levels (1-3), the terms will be very general.
Those terms have many associated genes, so, there will be a low
percentage of found genes from the user genes. The very specific terms
(e.g. level 12) have associated a small number of genes. In this case,
the percentage of found genes it is higher. Anyway, one has to consider
the complex hierarchical GO structure that makes the terms to be in
several levels. This feature is availabe while using a hierarchically
structured ontology source (e.g. GO).
Minimum number of identifiers from the uploaded cluster found to
be associated with a term.
Minimum percentage that the mapped identifiers are representing
from the total associated genes with the term

Fusion. The terms in parent-child relationship that share similar
genes (identical, or with one gene difference) are assessed and the most
representative parent or child term is retained. Note: This is an
optional feature. The fusion strongly reduces the redundancy.
Kappa Score shows the relationships between the terms based on
their overlapping genes. It is used for creating the network and can be
used for creating the groups. Initially, a term-gene matrix containing
the selected terms and their associated genes is created. Based on this,
a termterm similarity matrix is calculated using kappa statistics to
determine the association strength between the terms (kappa score). High
score = visualize in the network only the connections between close
related terms, with very similar associated genes (high stringency). Low
score = allows to visualize in the network the connections between less
related terms (low stringency).
Create functional groups. The terms can be associated in
functional groups using the ontology’s hierarchy or the kappa score.
When displaying the functional groups on the network, one has to
consider that the network structure is calculated with kappa score. The
kappa score grouping of the terms will correspond with the network
structure that is calculated in the same manner. If the hierarchical
grouping is used, it is possible to be a difference between the networks
structure (based on the associated genes) and the functional groups
defined using GO hierarchy.
Use fix coloring for the groups
Use random coloring for the groups
The most representative term in a group is giving the name of the
group. It can be considered having:
- the highest number of the found genes per term
- the highest percentage of found genes per term
- the highest percentage of found genes per total number of found
genes
- the most significant PValue This selection determines the ClueGO
charts display: the number/percentage/significance of the terms. If the
group leading term is the term with the higher number of genes or the
most significant term from the group, a label with the percentage of the
found genes compared with all the associated genes with the term is
displayed on the bars of the chart. Reversely, if the group leading term
is representing the percentage of genes (compared to all the genes
associated with the term or with all the genes found from the uploaded
cluster), on the label will be displayed the number of the genes found
for this term.
The hierarchy based grouping consists in analyzing the selected
terms through the perspective of their parent terms. The size of the
groups can be defined using the number of common and different parents,
that is depending on the level of the term in GO hierarchy. Since KEGG
and BioCarta don’t have a hierarchical structure, the terms selected
from those souces will not be grouped.
For grouping the terms based on the kappa score, it is necessary
to set the size of the initial group (e.g. 3) and the percentage
(overlaping terms/group) for group merge (e.g. 50 percent). For more
details see [4]. All the possible initial groups with the terms showing
a kappa score equal or above the predefined threshold (e.g.¡= 0.3) are
created. Further, the initial groups are iterratively compared and
merged if they are overlapping in the defined percentage. A term can be
part of several groups. The reocurrence of the term is shown by adding ”
n”. If the terms have very similar associated genes, it is possible that
the iterative merging of the created groups to take a longer time in the
attempt of merging all the groups. In this case, it is recommnended to
increase the kappa score level or to increase the percentage for group
merge.
Advanced Statistical Options
- Select mid-P-value for a less conservative hypergeometric test.
- Select Doubling for a less conservative two tailed hypergeometric
test.

Cluster Comparison
Once selected the option: ”Compare clusters”, two
file choosers are made available. The selection of the ontology terms is
following the same steps as in the analysis for a single cluster.
The difference refers to the number and the percentage of the genes
per term. Those selection criteria can be flexible: Cluster1 OR Cluster2
options (1) or applied strictly for both clusters: Cluster1 AND Cluster2
options (2).
It is recommended to have comparable number of identifiers in the
analysed clusters. If one cluster is much larger, the selection criteria
should be applied more strictly (e.g. increase the number of genes per
term).


Further, we analyze the terms trough the perspective of their
associated genes. It is possible that genes from both clusters will be
associated with a term, but in different proportions. We defined a term
as specific for one of the clusters if the percentage of associated
genes from this cluster is higher than the selected threshold (e.g. 66
percent) (3). As result, charts with specific terms for each cluster are
provided. The common terms are included in a separate chart.
On the network, the different proportion of the genes from the
analyzed clusters is represented with a color gradient from green, for
the first cluster genes, to red for the second cluster. The
visualization of the groups on the network can be switched with the one
of the uploaded clusters distribution on the selected terms (see Figure
below).

ClueGO result visualizations

Include your organism of interest in ClueGO
ClueGO allows to add new organisms, not included in our initial
selection. For each new organism, a keyIdentifier file:
organism.gene2accession.txt (e.g. Oryza Sativa.gene2accession) has to be
created. In this file, the first column (”UniqueID#EntrezGeneID”) will
contain the keyID (e.g. EntrezGeneID) that is used for mapping. Next
column, ”SymbolID” contains the official gene symbol or official symbol
and synonyms separated by ”|”. Other types of identifiers can be
included in the next columns.
The second file needed is organism.properties (e.g. Oryza
Sativa.properties). This file contains the organism name, the keggID,
the url of the GO association file, the taxonomy id. The same url can be
used for other organisms after changing the name of the annotation file.
In most of the cases, there are no special files required for the update
(false). Here is the content of the .properties file for Oryza sativa:
organism.name = Oryza sativa organism.kegg.name = osa organism.go.url =
ftp://anonymous:anonymous@ftp.geneontology.org/pub/go/gene-associations/gene
association.gramene oryza.gz organism.taxid = 39946
organism.update.needs.special.file = false Those files have to be added
in a new folder (e.g. Organism Oryza sativa) created in UserHomeFolder,
.cluegoplugin, currentVersion, ClueGOFiles, ClueGOSourceFiles. Remark:
At the addition of a new organism, make sure that the ids provided by
KEGG are the same as the UniqueIDs from organism.gene2accession.txt.
LS0tCnRpdGxlOiAnUGF0aHdheSBFbnJpY2htZW50IEFuYWx5c2lzIHVzaW5nIENsdWVHTyBhbmQgQ2x1ZVBlZGlhIC0gU2Vzc2lvbiAzJwphdXRob3I6ICJEci4gQWtzaGF5IEJoYXQiCmRhdGU6ICdgciBmb3JtYXQoU3lzLnRpbWUoKSwgIkxhc3QgbW9kaWZpZWQ6ICVkICViICVZIilgJwpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogICAgY3NzOiBzdHlsZXNoZWV0cy9zdHlsZXMuY3NzCiAgcGRmX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKLS0tCjxpbWcgc3JjPSJpbWFnZXMvbG9nby1zbS5wbmciIHN0eWxlPSJwb3NpdGlvbjphYnNvbHV0ZTt0b3A6NDBweDtyaWdodDoxMHB4OyIgd2lkdGg9IjIwMCIgLz4KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgdGlkeSA9IFRSVUUsCiAgdGlkeS5vcHRzID0gbGlzdCh3aWR0aC5jdXRvZmYgPSA5NSksCiAgbWVzc2FnZSA9IEZBTFNFLAogIHdhcm5pbmcgPSBGQUxTRSwKICBmaWcud2lkdGggPSAxMCwKICB0aW1lX2l0ID0gVFJVRQopCgpgYGAKCiMgSW50cm9kdWN0aW9uCgpJbiB0aGlzIHNlc3Npb24gd2Ugd2lsbCBsZWFybiBob3cgdG8gcGVyZm9ybSBwYXRod2F5IGVucmljaG1lbnQgYW5hbHlzaXMgdXNpbmcgZ2VuZSBzZXRzIGZyb20gb3VyIHRyYW5zY3JpcHRvbWljcyBleHBlcmltZW50IGFsc28gdGVybWVkIGFzICoqR2VuZS1TZXQgRW5yaWNobWVudCBBbmFseXNpcyAob3IgR1NFQSkqKi4gV2Ugd2lsbCB1c2UgdHdvIEN5dG9zY2FwZSBwbHVnaW5zIC0gQ2x1ZUdPIGFuZCBDbHVlUGVkaWEgd2hpY2ggYXJlIHRoZSBtb3N0IGhpZ2hseSByYXRlZCBvciB0b3AgZG93bmxvYWQgdG9vbHMgaW4gdGhlIChbY3l0b3NjYXBlIEFwcCBzdG9yZS5dKCJodHRwczovL2FwcHMuY3l0b3NjYXBlLm9yZy8iKSkuIAoKIVtdKGltYWdlcy9DeXRvc2NhcGVfQXBwX1N0b3JlLnBuZykKCiMjIEluc3RhbGxhdGlvbgoKKiBHbyB0byBodHRwczovL2FwcHMuY3l0b3NjYXBlLm9yZy9hcHBzL2NsdWVnbyBhbmQgY2xpY2sgKipEb3dubG9hZCoqIG9yICoqSW5zdGFsbCoqIChpZiB5b3VyIGN5dG9zY2FwZSBhcHBsaWNhdGlvbiBpcyBvcGVuKQoqIE1vcmUgb24gaW5zdGFsbGF0aW9uLCBkb2N1bWVudGF0aW9uIGFuZCBob3cgdG8gaW50ZWdyYXRlIHRoZSBwYWNrYWdlIHdpdGggUiBvciBQeXRob24gaXMgZGVzY3JpYmVkIChbaGVyZTpdKGh0dHA6Ly93d3cuaWNpLnVwbWMuZnIvY2x1ZWdvL2NsdWVnb0RvY3VtZW50YXRpb24uc2h0bWwpKQoqIEFsc28gZ28gdG8gaHR0cHM6Ly9hcHBzLmN5dG9zY2FwZS5vcmcvYXBwcy9jbHVlcGVkaWEgYW5kIGNsaWNrICoqRG93bmxvYWQqKiBvciAqKkluc3RhbGwqKiAoaWYgeW91ciBjeXRvc2NhcGUgYXBwbGljYXRpb24gaXMgb3BlbikKCgojIyBTeXN0ZW0gUmVxdWlyZW1lbnRzOiAKKiBXaW5kb3dzLCBMaW51eCwgVW5peCBvciBNYWNPUyBvcGVyYXRpbmcgc3lzdGVtLgoqIDE2IEdCIFJBTSByZWNvbW1lbmRlZC4gSGFyZCBkaXNrIHdpdGggYXQgbGVhc3QgMTAwIE1CIGZyZWUgKGZvciBleGFtcGxlIGZpbGVzKS4KKiBKYXZhIDEuOCsgbmVlZGVkIC0gKipWRVJZIEVTU0VOVElBTCoqLiAKKiAqKkN5dG9zY2FwZSAzLjcuKyoqIGluc3RhbGxlZDogaHR0cHM6Ly9jeXRvc2NhcGUub3JnLyAtIGxhdGVzdCBpcyAqKnZlcnNpb24gMy4xMC4xKiouCgoqKk5PVEU6KiogQXQgdGhlIGZpcnN0IHN0YXJ0dXAsIHRoZSBDbHVlR08gQ29uZmlndXJhdGlvbiBmb2xkZXIgY29udGFpbmluZyBwcmUtY29tcGlsZWQgQ2x1ZUdPIGZpbGVzCmFuZCBzYW1wbGUgZmlsZXMgd2lsbCBiZSBjcmVhdGVkIGluIHRoZSB1c2VyIGhvbWUgZm9sZGVyLiBJZiB0aGlzIGZvbGRlciBpcyByZW1vdmVkIG9yIHRoZSBjb250ZW50CmRhbWFnZWQsIGl0IHdpbGwgYmUgcmVjcmVhdGVkIGF1dG9tYXRpY2FsbHkgYXQgdGhlIG5leHQgc3RhcnR1cC4KCgojIyBMaWNlbnNlCgoqKkNsdWVHTyoqIGFuZCAqKkNsdWVQZWRpYSoqIGlzIGF2YWlsYWJsZSBmcmVlIG9mIGNoYXJnZSBvbmx5IHRvIGFjYWRlbWljLCBnb3Zlcm5tZW50LCBhbmQgb3RoZXIgbm9ucHJvZml0IGluc3RpdHV0aW9ucyBmb3Igbm9uY29tbWVyY2lhbCwgbm9ucHJvZml0IGludGVybmFsIHJlc2VhcmNoIHB1cnBvc2VzLiAKCgojIyBOb3RlIApUaGlzIGNvdXJzZSBpcyBpbnRlbmRlZCBmb3IgYW4gYXVkaWVuY2Ugd2hvIHdoaWNoIHRvIGFuYWx5c2UgYmlvbG9naWNhbCBkYXRhICh3aXRoIGFuIGV4YW1wbGUgb2YgUk5BLVNlcSkgYW5kIGhhdmUgbm8gcHJldmlvdXMgcHJvZ3JhbW1pbmcgZXhwZXJpZW5jZS4gSG93ZXZlciwgZm9yIHRob3NlIHdobyB3YW50IHRvIGludGVncmF0ZSBDeXRvc2NhcGUgKGFuZCBwYWNrYWdlcyBsaWtlIENsdWVHTyBhbmQgQ2x1ZVBlZGlhKSB1c2luZyBSIG9yIFB5dGhvbiwgdGhlbiBwbGVhc2UgcmVmZXIgdG8gaHR0cDovL3d3dy5pY2kudXBtYy5mci9jbHVlZ28vY2x1ZWdvRG9jdW1lbnRhdGlvbi5zaHRtbCB0byBvYnRhaW4gdGhlIHJlcXVpcmVkIEFQSS4gCgoKIyMgRG9jdW1lbnRhdGlvbgoKR2VuZXJhbGx5LCB0aGUgYmlvbG9naWNhbCBpbnRlcnByZXRhdGlvbiBvZiBsYXJnZSBnZW5lIGNsdXN0ZXJzIGRlcml2ZWQgZnJvbSBoaWdoLXRocm91Z2hwdXQgZXhwZXJpbWVudHMgaXMgYSByZWFsIGNoYWxsZW5nZS4gTWFueSBvbnRvbG9neSBzb3VyY2VzIGV4aXN0IGluIG9yZGVyIHRvIGNhcHR1cmUgYmlvbG9naWNhbCBpbmZvcm1hdGlvbiBpbiBhIG1lYW5pbmdmdWwgd2F5LgoKKipUaGUgR2VuZSBPbnRvbG9neSAoR08pIHByb2plY3RzKiogWzFdIGFpbXMgdG8gY2FwdHVyZSB0aGUgaW5jcmVhc2luZyBrbm93bGVkZ2Ugb24gZ2VuZSBmdW5jdGlvbiBpbiBhIGNvbnRyb2xsZWQgdm9jYWJ1bGFyeSBhcHBsaWNhYmxlIHRvIGFsbCB0aGUgb3JnYW5pc21zLiBHTyBkZXNjcmliZXMgZ2VuZSBwcm9kdWN0cyBpbiB0ZXJtcyBvZiB0aGVpciBhc3NvY2lhdGVkIGJpb2xvZ2ljYWwgcHJvY2Vzc2VzLCBjZWxsdWxhciBjb21wb25lbnRzIGFuZCBtb2xlY3VsYXIgZnVuY3Rpb25zLgoKQmV0d2VlbiB0aGUgdGVybXMgdGhlcmUgaXMgYSBoaWVyYXJjaGljYWwgcmVsYXRpb25zaGlwIChwYXJlbnQtY2hpbGQpLiBEdWUgdG8gdGhlIGNvbXBsZXhpdHkgb2YgaGllcmFyY2h5IHN0cnVjdHVyZSAoZGlyZWN0ZWQgYWN5Y2xpYyBncmFwaCksIHRoZSB0ZXJtcyBjYW4gYmUgaW4gc2V2ZXJhbCBkaWZmZXJlbnQgbGV2ZWxzLiBUaGUgc3BlY2lmaWNpdHkgb2YgdGhlIHRlcm1zIHZhcmllcyBhbG9uZyB0aGUgdHJlZTogZnJvbSB2ZXJ5IGdlbmVyYWwgdGVybXMgKGluIGZpcnN0IGxldmVscyBvZiBHTykgdG8gdmVyeSBzcGVjaWZpYyBvbmVzLgoKKipLeW90byBFbmN5Y2xvcGVkaWEgb2YgR2VuZXMgYW5kIEdlbm9tZXMgKEtFR0cpKiogWzJdIGlzIGEgZGF0YWJhc2Ugb2YgYmlvbG9naWNhbCBzeXN0ZW1zIHRoYXQgaW50ZWdyYXRlcyBnZW5vbWljLCBjaGVtaWNhbCBhbmQgc3lzdGVtaWMgZnVuY3Rpb25hbCBpbmZvcm1hdGlvbi4KCihbQmlvQ2FydGFdKCJodHRwOi8vd3d3LmJpb2NhcnRhLmNvbS8iKSkgcHJvdmlkZXMgdXNlZnVsbCBwYXRod2F5IGluZm9ybWF0aW9uLgoKRm9yIGEgY29tcGxldGUgdmlldyBvbiB0aGUgc3R1ZGllZCBwcm9jZXNzLCBzZXZlcmFsIG9udG9sb2d5IHNvdXJjZXMgc2hvdWxkIGJlIGNvbnN1bHRlZCBpbiBvcmRlciB0byBpbnRlZ3JhdGUgdGhlaXIgY29tcGxlbWVudGFyeSBpbmZvcm1hdGlvbi4gSW4gZWFjaCBzb3VyY2UsIGZvciBlYWNoIGdlbmUsIHRoZXJlIGlzIGEgbGFyZ2UgYW1vdW50IG9mIGluZm9ybWF0aW9uLiBUaGlzIG1ha2VzIHRoZSBhbmFseXNpcyBvZiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gZ2VuZXMgYW5kIGJldHdlZW4gdGVybXMgdmVyeSBkaWZmaWN1bHQgdG8gcmVwcmVzZW50IGFuZCBjb21wcmVoZW5kLiBBbHNvLCBmb3IgY2xvc2UgcmVsYXRlZCB0ZXJtcywgYSBoaWdoIGRlZ3JlZSBvZiByZWR1bmRhbmN5IG9mIHRoZWlyIGFzc29jaWF0ZWQgZ2VuZXMgZXhpc3RzLgoKKipDbHVlR08qKiwgYW4gb3Blbi1zb3VyY2UgSmF2YSB0b29sIHRoYXQgZXh0cmFjdHMgdGhlIG5vbi1yZWR1bmRhbnQgYmlvbG9naWNhbCBpbmZvcm1hdGlvbiBmb3IgbGFyZ2UgY2x1c3RlcnMgb2YgZ2VuZXMsIHVzaW5nIEdPLCBLRUdHIGFuZCBCaW9DYXJ0YS4gQ2x1ZUdPIGlzIGludGVncmF0ZWQgaW4gKipDeXRvc2NhcGUqKiAoaHR0cHM6Ly9jeXRvc2NhcGUub3JnLykgYXMgYSBwbHVnLWluIGFuZCBpdCBpcyB0YWtpbmcgYWR2YW50YWdlIG9mIGl0cyBjb21wbGV4IHZpc3VhbGl6YXRpb24gZW52aXJvbm1lbnQuCioqQ2x1ZUdPKiogZmVhdHVyZXMgaW5jbHVkZToKCiogQ2x1ZUdPIGFsbG93cyBhbmFseXNpcyBvZiBhIHNpbmdsZSBnZW5lIHNldCAoY2x1c3Rlcikgb3IgY2x1c3RlciBjb21wYXJpc29uLgoqIERpZmZlcmVudCBmaWx0ZXIgY3JpdGVyaWEgY2FuIGJlIGFwcGxpZWQgdG8gdGhlIHRlcm1zLgoqIEZ1c2lvbiBvZiB0aGUgcmVsYXRlZCB0ZXJtcyB0aGF0IGhhdmUgc2ltaWxhciBhc3NvY2lhdGVkIGdlbmVzLgoqIEZ1bmN0aW9uYWwgZ3JvdXBpbmcgb2YgdGhlIHRlcm1zIGJhc2VkIG9uIEdPIGhpZXJhcmNoeSBvciBiYXNlZCBvbiBrYXBwYSBzY29yZS4KKiBWaXN1YWxpemUgdGhlIHNlbGVjdGVkIHRlcm1zIGluIGEgZnVuY3Rpb25hbGx5IGdyb3VwZWQgbmV0d29yay4KKiBDaGFydHMgcHJlc2VudGluZyB0aGUgc3BlY2lmaWMgdGVybXMgYW5kIGdyb3VwcyBmb3IgdGhlIGNsdXN0ZXJzIGNvbXBhcmVkLgoqIFN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSBmb3IgdGhlIHRlcm1zIGFuZCBmb3IgdGhlIGdyb3Vwcy4KKiBDbHVlR08gY2FuIGJlIHVzZWQgaW4gY29tYmluYXRpb24gd2l0aCBHT2xvcml6ZS4KKiBFYXN5IHVwZGF0YWJsZS4KKiBFYXN5IGV4dGVuZGFibGUuCgoKIyMgU2VsZWN0aW9uIFBhbmVsCgpBZnRlciBzdGFydGluZyBDeXRvc2NhcGUsICoqQ2x1ZUdPKiogY2FuIGJlIGZvdW5kIHVuZGVyIHRoZSBQbHVnaW5zIG1lbnUuIE9uY2Ugc2VsZWN0ZWQsIGl0IHdpbGwgZGlzcGxheSB0aGUgQ2x1ZUdPIHNlbGVjdGlvbiBwYW5lbCBvcHRpb25zLiBTZWUgRmlndXJlIGJlbG93OgoKMS4gU2VsZWN0IHRoZSB0eXBlIG9mIGFuYWx5c2lzLiBCZXNpZGVzIGFuYWx5c2lzIG9mIGEgc2luZ2xlIGdlbmUgc2V0IChjbHVzdGVyKSwgQ2x1ZUdPIHBlcmZvcm1zIGNvbXBhcmlzb24gb2YgY2x1c3RlcnMsIHVuZGVybHlpbmcgdGhlIHNwZWNpZmljaXR5IGFuZCBhbHNvIHRoZSBjb21tb24gYXNwZWN0cyBvZiB0aGVpciBmdW5jdGlvbmFsaXR5LgoKIVtdKGltYWdlcy9DbHVlR09fU2VsZWN0aW9uUGFuZWwucG5nKQoKMi4gU2VsZWN0IG9yZ2FuaXNtLiBGb3IgdGhlIG1vbWVudCwgQ2x1ZUdPIHN1cHBvcnRzIEFyYWJpZG9wc2lzIHRoYWxpYW5hLCBCb3MgdGF1cnVzLCBDYWVub3JoYWJkaXRpcyBlbGVnYW5zLCBEYW5pbyByZXJpbywgRGljdHlvc3RlbGl1bSBkaXNjb2lkZXVtLCBEcm9zb3BoaWxhIG1lbGFub2dhc3RlciwgRXNjaGVyaWNoaWEgY29saSwKR2FsdXMgZ2FsdXMsIEhvbW8gc2FwaWVucywgTWFnbmFwb3J0aGUgZ3Jpc2VhLCBNdXMgbXVzY3VsdXMsIE9yeXphIHNhdGl2YSwgUmF0dHVzIG5vcnZlZ2ljdXMsClNhY2NoYXJvbXljZXMgY2VyZXZpc2lhZS4KMy4gU2VsZWN0IGlkZW50aWZpZXJzIHR5cGUgKEFmZnltZXRyaXhJRCwgQWNjZXNzaW9uSUQsIFN5bWJvbElEKS4KNC4gVGhlIGlkZW50aWZpZXJzIGNhbiBiZSB1cGxvYWRlZCBmcm9tIHRleHQgZmlsZXMgb3IgaW50ZXJhY3RpdmVseSBmcm9tIGEgQ3l0b3NjYXBlIHN1Yi1uZXR3b3JrLgpDbHVlR08gcHJvdmlkZXMgc2FtcGxlIGZpbGVzIGNvbnRhaW5pbmcgc3BlY2lmaWMgZ2VuZXMgKEFjY2Vzc2lvbklEKSBmb3IgSHVtYW4gQiBhbmQgTksgY2VsbHMuCkEgU2FjY2Fyb215Y2VzIG5ldHdvcmsgc2FtcGxlIChnYWxGaWx0ZXJlZC5jeXMpIGNhbiBiZSBmb3VuZCBpbiB0aGUgQ3l0b3NjYXBlIHNhbXBsZURhdGEKZm9sZGVyLgo1LiBDaG9vc2UgdGhlIGZpbGUgd2l0aCBpZGVudGlmaWVycy4KNi4gU2VsZWN0IHRoZSBvbnRvbG9neS9vbnRvbG9naWVzLiBUbyBtYWtlIENsdWVHTyBmYXN0ZXIsIHdlIHVzZSBwcmVjb21waWxlZCBmaWxlcyBiYXNlZCBvbiBHTywKS0VHRyBhbmQgQmlvQ2FydGEuIFRoZSBwcmVjb21waWxlZCBmaWxlcyBhcmUgaW5jbHVkZWQgaW4gdGhlIENsdWVHT1BsdWdpbi5qYXIuCjcuIFNlbGVjdCB0aGUgZXZpZGVuY2UgY29kZSwgb3B0aW9uIGF2YWlsYWJsZSBmb3IgdGhlIEdPIGJhc2VkIGZpbGVzLiBGb3IgbW9yZSBkZXRhaWxzLCBzZWUKaHR0cDovL3d3dy5nZW5lb250b2xvZ3kub3JnL0dPLmV2aWRlbmNlLnNodG1sLgo4LiBVcGRhdGUgdGhlIG9udG9sb2d5IChzZWUgQ2x1ZUdPIHVwZGF0ZXMpCjkuIFRoZSBzaWduaWZpY2FuY2Ugb2YgZWFjaCB0ZXJtIG9yIGdyb3VwIGNhbiBiZSBjYWxjdWxhdGVkIHdpdGggaHlwZXJnZW9tZXRyaWMgdGVzdCAoZW5yaWNobWVudCwKZGVwbGV0aW9uKS4gU3RhbmRhcmQgaXMgaHlwZXJnZW9tZXRyaWMgdGVzdCB0d28gc2lkZWQuCjEwLiBTZXZlcmFsIG1ldGhvZHMgZm9yIFBWYWx1ZSBjb3JyZWN0aW9uIGFyZSBwcm9wb3NlZDogQm9uZmVycm9uaSwgQm9uZmVycm9uaSBzdGVwLWRvd24gYW5kIEJlbmphbWluaUhvY2hiZXJnLgoxMS4gQWR2YW5jZWQgc3RhdGlzdGljYWwgb3B0aW9ucwoxMi4gU2VsZWN0IG5ldHdvcmsgdHlwZS4gV2UgcHJlZGVmaW5lZCBzZWxlY3Rpb24gY3JpdGVyaWEgbGVhZGluZyB0byBhIOKAnUdsb2JhbOKAnSBuZXR3b3JrLCBhIOKAnU1lZGl1beKAnQpuZXR3b3JrIG9yIGEg4oCdRGV0YWlsZWTigJ0gbmV0d29yay4KVGhlIOKAnUdsb2JhbOKAnSBuZXR3b3JrIGRpc3BsYXlzIEdPIHRlcm1zIGZvdW5kIGluIHRoZSBHTyBsZXZlbHMgMS0zLCB3aXRoIGEgaGlnaCBudW1iZXIgb2YKZ2VuZXMgYXNzb2NpYXRlZCBhbmQgYSBzbWFsbCBwZXJjZW50YWdlIG9mIHVwbG9hZGVkIGdlbmVzIGZvdW5kLiBUaG9zZSB0ZXJtcyBwcm92aWRlIGEgZ2VuZXJhbApiaW9sb2dpY2FsIGluZm9ybWF0aW9uLiBBdCB0aGUgb3Bwb3NpdGUsIHRoZSDigJ1EZXRhaWxlZOKAnSBuZXR3b3JrIHNob3dzIHZlcnkgc3BlY2lmaWMgdGVybXMgcGxhY2VkCmluIEdPIGxldmVscyA5LTE0LCB3aXRoIG9ubHkgZmV3IGFzc29jaWF0ZWQgZ2VuZXMgYnV0IGEgaGlnaCBwZXJjZW50YWdlIG9mIHRoZSB1cGxvYWRlZCBnZW5lcwpmb3VuZC4gVGhvc2UgdGVybXMgYXJlIG1vcmUgc3BlY2lmaWMgYW5kIGluZm9ybWF0aXZlIHVuZGVybHlpbmcgcGFydGljdWxhciBhc3BlY3RzIG9mIHRoZSBzdHVkaWVkCmdlbmUgcHJvZHVjdC4KVGhlIHByZWRlZmluZWQgc2V0dGluZ3MgcHJvdmlkZWQgYnkgQ2x1ZUdPIHNob3VsZCBiZSBjb21iaW5lZCB3aXRoIGEgY3VzdG9taXplZCBzZWxlY3Rpb24gZm9yCmFuIGFuYWx5c2lzIGFkYXB0ZWQgdG8gdGhlIGJpb2xvZ2ljYWwgcXVlc3Rpb24gYWRkcmVzc2VkIChnZW5lcmFsL3NwZWNpZmljIGludmVzdGlnYXRpb24pIGFuZCB0byB0aGUKbnVtYmVyIG9mIGdlbmVzIGludm9sdmVkLgoxMy4gQWR2YW5jZWQgc2V0dGluZ3MuCjE0LiBTdGFydCB0aGUgYW5hbHlzaXMuCgoKIyMgQ2x1ZUdPIHJlc3VsdAoKQSBmdW5jdGlvbmFsbHkgZ3JvdXBlZCBhbm5vdGF0aW9uIG5ldHdvcmssIGEgQ2x1ZUdPIGluZm9ybWF0aW9uIHRhYmxlLCBjaGFydHMgd2l0aCB0ZXJtcyBhbmQgZ3JvdXBzCmFuZCB0aGUgbG9naW5nIGluZm9ybWF0aW9uIGFyZSB0aGUgcmVzdWx0IG9mIENsdWVHTyBhbmFseXNpcy4gVGhlIGNyZWF0ZWQgbmV0d29ya3MgYW5kIGFuYWx5c2lzIHJlc3VsdHMKY2FuIGJlIHNhdmVkIGluIGEgc3BlY2lmaWVkIHByb2plY3QgZm9sZGVyIGFuZCB1c2VkIGZvciBmdXJ0aGVyIGFuYWx5c2lzLiBJZiB0aGUgYW5hbHlzaXMgaXMgbm90IG5lZWRlZAphbnltb3JlLCBpdCBpcyByZWNvbW1lbmRlZCB0byBjbG9zZSB0aGUgcHJvamVjdC4KCiFbXShpbWFnZXMvQ2x1ZUdvLVJlc3VsdHMucG5nKQoKCiMjIEZ1bmN0aW9uYWxseSBHcm91cGVkIEFubm90YXRpb24gTmV0d29yawoKQ2x1ZUdPIHZpc3VhbGl6ZXMgdGhlIHNlbGVjdGVkIHRlcm1zIGluIGEgZnVuY3Rpb25hbGx5IGdyb3VwZWQgYW5ub3RhdGlvbiBuZXR3b3JrIChTZWUgRmlndXJlIDIpIHRoYXQKcmVmbGVjdHMgdGhlIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiB0aGUgdGVybXMgYmFzZWQgb24gdGhlIHNpbWlsYXJpdHkgb2YgdGhlaXIgYXNzb2NpYXRlZCBnZW5lcy4gVGhlIHNpemUKb2YgdGhlIG5vZGVzIHJlZmxlY3RzIHRoZSBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2Ugb2YgdGhlIHRlcm1zLiBUaGUgZGVncmVlIG9mIGNvbm5lY3Rpdml0eSBiZXR3ZWVuIHRlcm1zCihlZGdlcykgaXMgY2FsY3VsYXRlZCB1c2luZyBrYXBwYSBzdGF0aXN0aWNzLCBpbiBhIHNpbWlsYXIgd2F5IGFzIGRlc2NyaWJlZCBpbiBbNF0uIFRoZSBjYWxjdWxhdGVkIGthcHBhCnNjb3JlIGlzIGFsc28gdXNlZCBmb3IgZGVmaW5pbmcgZnVuY3Rpb25hbCBncm91cHMuIEEgdGVybSBjYW4gYmUgaW5jbHVkZWQgaW4gc2V2ZXJhbCBncm91cHMuIFRoZSByZW9jdXJyZW5jZSBvZiB0aGUgdGVybSBpcyBzaG93biBieSBhZGRpbmcg4oCdIG7igJ0uIFRoZSBub3QgZ3JvdXBlZCB0ZXJtcyBhcmUgc2hvd24gaW4gd2hpdGUgY29sb3IuIFByZWRlZmluZWQsCnRoZSBncm91cCBsZWFkaW5nIHRlcm0gaXMgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgdGVybSBvZiB0aGUgZ3JvdXAuIFRoZSBuZXR3b3JrIGludGVncmF0ZXMgb25seSB0aGUgcG9zaXRpdmUKa2FwcGEgc2NvcmUgdGVybSBhc3NvY2lhdGlvbnMgYW5kIGlzIGF1dG9tYXRpY2FsbHkgbGFpZCBvdXQgdXNpbmcgT3JnYW5pYyBsYXlvdXQgYWxnb3JpdGhtIHN1cHBvcnRlZCBieQpDeXRvc2NhcGUuCgoKIyMgSW5mb3JtYXRpb24gdGFibGUKCioqQ2x1ZUdPKiogSW5mb3JtYXRpb24gdGFibGUgcHJvdmlkZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHNlbGVjdGVkIHRlcm1zLiBGcm9tIGxlZnQgdG8gcmlnaHQ6CgoxLiBHcm91cCBsZWFkaW5nIHRlcm0uIFRoZXJlIGFyZSBzZXZlcmFsIHdheXMgb2YgZGVmaW5pbmcgdGhlIGxlYWRpbmcgdGVybSBvZiB0aGUgZ3JvdXAgKHNlZSBBZHZhbmNlZCBTZXR0aW5ncykuIFByZWRlZmluZWQsIHRoZSBsZWFkaW5nIHRlcm0gaGFzIHRoZSBoaWdoZXN0IHNpZ25pZmljYW5jZSBpbiB0aGUgZ3JvdXAuCgohW10oaW1hZ2VzL0NsdWVHTy1pbmZvVGFibGUucG5nKQoKMi4gR09JRC4KMy4gR08gVGVybS4KNC4gT250b2xvZ3kgU291cmNlLgo1LiBHTyBsZXZlbHMuIER1ZSB0byB0aGUgY29tcGxleCBzdHJ1Y3R1cmUgb2YgR08gdHJlZSAoZGlyZWN0ZWQgYWN5Y2xpYyBncmFwaCksIHRoZSBHTyB0ZXJtcyBjYW4gYmUKcGxhY2VkIGluIHNldmVyYWwgbGV2ZWxzLiBJbiBjYXNlIG9mIHVzaW5nIHNvdXJjZXMgd2l0aG91dCBoaWVyYXJjaGljYWwgc3RydWN0dXJlIChLRUdHLCBCaW9DYXJ0YSksCnRoZSBsZXZlbCBpdCBpcyBhc3NpZ25lZCBhcyAtMS4KNi4gVGhlIGdyb3VwIG9yIHRoZSBncm91cHMgdGhhdCBpbmNsdWRlIHRoZSB0ZXJtLgo3LiBUaGUgcGVyY2VudGFnZSBvZiB0aGUgZ2VuZXMgZnJvbSB0aGUgdXBsb2FkZWQgY2x1c3RlciB0aGF0IHdlcmUgYXNzb2NpYXRlZCB3aXRoIHRoZSB0ZXJtLCBjb21wYXJlZCB3aXRoIGFsbCB0aGUgZ2VuZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSB0ZXJtLgo4LiBUaGUgbnVtYmVyIHRoZSBnZW5lcyBmcm9tIHRoZSB1cGxvYWRlZCBjbHVzdGVyIHRoYXQgd2VyZSBhc3NvY2lhdGVkIHdpdGggdGhlIHRlcm0uCjkuIFRlcm0gc2lnbmlmaWNhbmNlIChQVmFsdWUpLgoxMC4gVGVybSBzaWduaWZpY2FuY2UgKGNvcnJlY3RlZCBQVmFsdWUpLgoxMS4gR3JvdXAgc2lnbmlmaWNhbmNlIChQVmFsdWUpLgoxMi4gR3JvdXAgc2lnbmlmaWNhbmNlIChjb3JyZWN0ZWQgUFZhbHVlKS4KMTMuIFRoZSBnZW5lcyBmcm9tIHRoZSB1cGxvYWRlZCBjbHVzdGVyIHRoYXQgd2VyZSBhc3NvY2lhdGVkIHdpdGggdGhlIHRlcm0uCgojIyBIaXN0b2dyYW0gd2l0aCB0ZXJtcwoKVGhlIGNoYXJ0IHByZXNlbnRzIHRoZSBzcGVjaWZpYyB0ZXJtcyBmb3IgdGhlIHVzZXIgZ2VuZXMgYW5kIGluZm9ybWF0aW9uIHJlbGF0ZWQgdG8gdGhlaXIgYXNzb2NpYXRlZCBnZW5lcy4KVGhlIGRpc3BsYXkgY2FuIGJlIGN1c3RvbWl6ZWQgKHNlZSBBZHZhbmNlZCBzZXR0aW5ncykuIFByZWRlZmluZWQsIHRoZSBiYXJzIHJlcHJlc2VudCB0aGUgbnVtYmVyIG9mCnRoZSBnZW5lcyBmcm9tIHRoZSBhbmFseXplZCBjbHVzdGVyIGZvdW5kIGFzc29jaWF0ZWQgd2l0aCB0aGUgdGVybSwgYW5kIHRoZSBsYWJlbCBkaXNwbGF5ZWQgb24gdGhlIGJhcnMKaXMgdGhlIHBlcmNlbnRhZ2Ugb2YgZm91bmQgZ2VuZXMgY29tcGFyZWQgdG8gYWxsIHRoZSBnZW5lcyBhc3NvY2lhdGVkIHdpdGggdGhlIHRlcm0uIFRlcm0gc2lnbmlmaWNhbmNlCmluZm9ybWF0aW9uIGlzIGluY2x1ZGVkIGluIHRoZSBjaGFydCAoc2VlIFN0YXRpc3RpY3MpLgoKIVtdKGltYWdlcy9DbHVlR08taGlzdG9ncmFtLnBuZykKCgojIyBPdmVydmlldyBDaGFydCB3aXRoIGZ1bmN0aW9uYWwgZ3JvdXBzCgpUaGUgb3ZlcnZpZXcgY2hhcnQgcHJlc2VudHMgZnVuY3Rpb25hbCBncm91cHMgZm9yIHRoZSB1c2VyIGdlbmVzLiBUaGUgbmFtZSBvZiB0aGUgZ3JvdXAgaXMgZ2l2ZW4gYnkgdGhlCmdyb3VwIGxlYWRpbmcgdGVybSAoZS5nLiB0aGUgbW9zdCBzaWduaWZpY2FudCB0ZXJtIGluIHRoZSBncm91cCkuIFRoZSBncm91cCBzZWN0aW9ucyBjb3JyZWxhdGUgd2l0aCB0aGUKbnVtYmVyIG9mIHRoZSB0ZXJtcyBpbmNsdWRlZCBpbiBncm91cC4gVGhlIHBvc2l0aW9uIG9mIHRoZSBzZWN0aW9ucyBjYW4gYmUgY2hhbmdlZCAocmlnaHQgY2xpY2spLgoKIyMgTG9naW5nIGluZm9ybWF0aW9uCgpDb21wbGV0ZSBpbmZvcm1hdGlvbiBvbiB0aGUgYXBwbGllZCBzZWxlY3Rpb24gY3JpdGVyaWEgZm9yIGVhY2ggYW5hbHlzaXMgY2FuIGJlIHZpc3VhbGl6ZWQgaW4gdGhlIGxvZ2luZwppbmZvcm1hdGlvbiBwYW5lbC4KCiFbXShpbWFnZXMvQ2x1ZUdPLUxvZ2luSW5mby5wbmcpCgojIyBBZHZhbmNlZCBTZXR0aW5ncwoKQ2x1ZUdPIGFkdmFuY2VkIHNldHRpbmdzIGFsbG93cyBhIHByZWNpc2UgYWRqdXN0bWVudCBvZiB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhLgoKIVtdKGltYWdlcy9DbHVlR08tRnVuY3Rpb25hbEdyb3Vwcy5wbmcpCgoKCjEuIEdPIHRyZWUgbGV2ZWwuIFRoZSBpZGVudGlmaWVycyBjYW4gYmUgbWFwcGVkIGluIHRoZSBlbnRpcmUgb250b2xvZ3kgdHJlZSBvciBpbiBhIEdPIGxldmVsIGludGVydmFsCihiZXR3ZWVuIE1pbiBhbmQgTWF4IGxldmVscykuIElmIHNlbGVjdGVkIHRoZSBmaXJzdCBHTyBsZXZlbHMgKDEtMyksIHRoZSB0ZXJtcyB3aWxsIGJlIHZlcnkgZ2VuZXJhbC4KVGhvc2UgdGVybXMgaGF2ZSBtYW55IGFzc29jaWF0ZWQgZ2VuZXMsIHNvLCB0aGVyZSB3aWxsIGJlIGEgbG93IHBlcmNlbnRhZ2Ugb2YgZm91bmQgZ2VuZXMgZnJvbQp0aGUgdXNlciBnZW5lcy4gVGhlIHZlcnkgc3BlY2lmaWMgdGVybXMgKGUuZy4gbGV2ZWwgMTIpIGhhdmUgYXNzb2NpYXRlZCBhIHNtYWxsIG51bWJlciBvZiBnZW5lcy4KSW4gdGhpcyBjYXNlLCB0aGUgcGVyY2VudGFnZSBvZiBmb3VuZCBnZW5lcyBpdCBpcyBoaWdoZXIuIEFueXdheSwgb25lIGhhcyB0byBjb25zaWRlciB0aGUgY29tcGxleApoaWVyYXJjaGljYWwgR08gc3RydWN0dXJlIHRoYXQgbWFrZXMgdGhlIHRlcm1zIHRvIGJlIGluIHNldmVyYWwgbGV2ZWxzLiBUaGlzIGZlYXR1cmUgaXMgYXZhaWxhYmUKd2hpbGUgdXNpbmcgYSBoaWVyYXJjaGljYWxseSBzdHJ1Y3R1cmVkIG9udG9sb2d5IHNvdXJjZSAoZS5nLiBHTykuCgoyLiBNaW5pbXVtIG51bWJlciBvZiBpZGVudGlmaWVycyBmcm9tIHRoZSB1cGxvYWRlZCBjbHVzdGVyIGZvdW5kIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCBhIHRlcm0uCgozLiBNaW5pbXVtIHBlcmNlbnRhZ2UgdGhhdCB0aGUgbWFwcGVkIGlkZW50aWZpZXJzIGFyZSByZXByZXNlbnRpbmcgZnJvbSB0aGUgdG90YWwgYXNzb2NpYXRlZCBnZW5lcwp3aXRoIHRoZSB0ZXJtCgohW10oaW1hZ2VzL0NsdWVHTy1BZHZhbmNlZFNldHRpbmdzLnBuZykKCgo0LiBGdXNpb24uIFRoZSB0ZXJtcyBpbiBwYXJlbnQtY2hpbGQgcmVsYXRpb25zaGlwIHRoYXQgc2hhcmUgc2ltaWxhciBnZW5lcyAoaWRlbnRpY2FsLCBvciB3aXRoIG9uZSBnZW5lCmRpZmZlcmVuY2UpIGFyZSBhc3Nlc3NlZCBhbmQgdGhlIG1vc3QgcmVwcmVzZW50YXRpdmUgcGFyZW50IG9yIGNoaWxkIHRlcm0gaXMgcmV0YWluZWQuCk5vdGU6IFRoaXMgaXMgYW4gb3B0aW9uYWwgZmVhdHVyZS4gVGhlIGZ1c2lvbiBzdHJvbmdseSByZWR1Y2VzIHRoZSByZWR1bmRhbmN5Lgo1LiBLYXBwYSBTY29yZSBzaG93cyB0aGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHRoZSB0ZXJtcyBiYXNlZCBvbiB0aGVpciBvdmVybGFwcGluZyBnZW5lcy4gSXQgaXMKdXNlZCBmb3IgY3JlYXRpbmcgdGhlIG5ldHdvcmsgYW5kIGNhbiBiZSB1c2VkIGZvciBjcmVhdGluZyB0aGUgZ3JvdXBzLiBJbml0aWFsbHksIGEgdGVybS1nZW5lCm1hdHJpeCBjb250YWluaW5nIHRoZSBzZWxlY3RlZCB0ZXJtcyBhbmQgdGhlaXIgYXNzb2NpYXRlZCBnZW5lcyBpcyBjcmVhdGVkLiBCYXNlZCBvbiB0aGlzLCBhIHRlcm10ZXJtIHNpbWlsYXJpdHkgbWF0cml4IGlzIGNhbGN1bGF0ZWQgdXNpbmcga2FwcGEgc3RhdGlzdGljcyB0byBkZXRlcm1pbmUgdGhlIGFzc29jaWF0aW9uIHN0cmVuZ3RoCmJldHdlZW4gdGhlIHRlcm1zIChrYXBwYSBzY29yZSkuIEhpZ2ggc2NvcmUgPSB2aXN1YWxpemUgaW4gdGhlIG5ldHdvcmsgb25seSB0aGUgY29ubmVjdGlvbnMKYmV0d2VlbiBjbG9zZSByZWxhdGVkIHRlcm1zLCB3aXRoIHZlcnkgc2ltaWxhciBhc3NvY2lhdGVkIGdlbmVzIChoaWdoIHN0cmluZ2VuY3kpLiBMb3cgc2NvcmUgPQphbGxvd3MgdG8gdmlzdWFsaXplIGluIHRoZSBuZXR3b3JrIHRoZSBjb25uZWN0aW9ucyBiZXR3ZWVuIGxlc3MgcmVsYXRlZCB0ZXJtcyAobG93IHN0cmluZ2VuY3kpLgo2LiBDcmVhdGUgZnVuY3Rpb25hbCBncm91cHMuIFRoZSB0ZXJtcyBjYW4gYmUgYXNzb2NpYXRlZCBpbiBmdW5jdGlvbmFsIGdyb3VwcyB1c2luZyB0aGUgb250b2xvZ3nigJlzCmhpZXJhcmNoeSBvciB0aGUga2FwcGEgc2NvcmUuCldoZW4gZGlzcGxheWluZyB0aGUgZnVuY3Rpb25hbCBncm91cHMgb24gdGhlIG5ldHdvcmssIG9uZSBoYXMgdG8gY29uc2lkZXIgdGhhdCB0aGUgbmV0d29yayBzdHJ1Y3R1cmUgaXMgY2FsY3VsYXRlZCB3aXRoIGthcHBhIHNjb3JlLiBUaGUga2FwcGEgc2NvcmUgZ3JvdXBpbmcgb2YgdGhlIHRlcm1zIHdpbGwgY29ycmVzcG9uZCB3aXRoCnRoZSBuZXR3b3JrIHN0cnVjdHVyZSB0aGF0IGlzIGNhbGN1bGF0ZWQgaW4gdGhlIHNhbWUgbWFubmVyLiBJZiB0aGUgaGllcmFyY2hpY2FsIGdyb3VwaW5nIGlzIHVzZWQsIGl0CmlzIHBvc3NpYmxlIHRvIGJlIGEgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBuZXR3b3JrcyBzdHJ1Y3R1cmUgKGJhc2VkIG9uIHRoZSBhc3NvY2lhdGVkIGdlbmVzKSBhbmQKdGhlIGZ1bmN0aW9uYWwgZ3JvdXBzIGRlZmluZWQgdXNpbmcgR08gaGllcmFyY2h5LgoKNy4gVXNlIGZpeCBjb2xvcmluZyBmb3IgdGhlIGdyb3Vwcwo4LiBVc2UgcmFuZG9tIGNvbG9yaW5nIGZvciB0aGUgZ3JvdXBzCjkuIFRoZSBtb3N0IHJlcHJlc2VudGF0aXZlIHRlcm0gaW4gYSBncm91cCBpcyBnaXZpbmcgdGhlIG5hbWUgb2YgdGhlIGdyb3VwLiBJdCBjYW4gYmUgY29uc2lkZXJlZCBoYXZpbmc6CiAgYSkgdGhlIGhpZ2hlc3QgbnVtYmVyIG9mIHRoZSBmb3VuZCBnZW5lcyBwZXIgdGVybQogIGIpIHRoZSBoaWdoZXN0IHBlcmNlbnRhZ2Ugb2YgZm91bmQgZ2VuZXMgcGVyIHRlcm0KICBjKSB0aGUgaGlnaGVzdCBwZXJjZW50YWdlIG9mIGZvdW5kIGdlbmVzIHBlciB0b3RhbCBudW1iZXIgb2YgZm91bmQgZ2VuZXMKICBkKSB0aGUgbW9zdCBzaWduaWZpY2FudCBQVmFsdWUKVGhpcyBzZWxlY3Rpb24gZGV0ZXJtaW5lcyB0aGUgQ2x1ZUdPIGNoYXJ0cyBkaXNwbGF5OiB0aGUgbnVtYmVyL3BlcmNlbnRhZ2Uvc2lnbmlmaWNhbmNlIG9mIHRoZQp0ZXJtcy4gSWYgdGhlIGdyb3VwIGxlYWRpbmcgdGVybSBpcyB0aGUgdGVybSB3aXRoIHRoZSBoaWdoZXIgbnVtYmVyIG9mIGdlbmVzIG9yIHRoZSBtb3N0IHNpZ25pZmljYW50IHRlcm0gZnJvbSB0aGUgZ3JvdXAsIGEgbGFiZWwgd2l0aCB0aGUgcGVyY2VudGFnZSBvZiB0aGUgZm91bmQgZ2VuZXMgY29tcGFyZWQgd2l0aCBhbGwgdGhlCmFzc29jaWF0ZWQgZ2VuZXMgd2l0aCB0aGUgdGVybSBpcyBkaXNwbGF5ZWQgb24gdGhlIGJhcnMgb2YgdGhlIGNoYXJ0LiBSZXZlcnNlbHksIGlmIHRoZSBncm91cCBsZWFkaW5nCnRlcm0gaXMgcmVwcmVzZW50aW5nIHRoZSBwZXJjZW50YWdlIG9mIGdlbmVzIChjb21wYXJlZCB0byBhbGwgdGhlIGdlbmVzIGFzc29jaWF0ZWQgd2l0aCB0aGUgdGVybQpvciB3aXRoIGFsbCB0aGUgZ2VuZXMgZm91bmQgZnJvbSB0aGUgdXBsb2FkZWQgY2x1c3RlciksIG9uIHRoZSBsYWJlbCB3aWxsIGJlIGRpc3BsYXllZCB0aGUgbnVtYmVyCm9mIHRoZSBnZW5lcyBmb3VuZCBmb3IgdGhpcyB0ZXJtLgoKMTAuIFRoZSBoaWVyYXJjaHkgYmFzZWQgZ3JvdXBpbmcgY29uc2lzdHMgaW4gYW5hbHl6aW5nIHRoZSBzZWxlY3RlZCB0ZXJtcyB0aHJvdWdoIHRoZSBwZXJzcGVjdGl2ZQpvZiB0aGVpciBwYXJlbnQgdGVybXMuIFRoZSBzaXplIG9mIHRoZSBncm91cHMgY2FuIGJlIGRlZmluZWQgdXNpbmcgdGhlIG51bWJlciBvZiBjb21tb24gYW5kCmRpZmZlcmVudCBwYXJlbnRzLCB0aGF0IGlzIGRlcGVuZGluZyBvbiB0aGUgbGV2ZWwgb2YgdGhlIHRlcm0gaW4gR08gaGllcmFyY2h5LiBTaW5jZSBLRUdHIGFuZApCaW9DYXJ0YSBkb27igJl0IGhhdmUgYSBoaWVyYXJjaGljYWwgc3RydWN0dXJlLCB0aGUgdGVybXMgc2VsZWN0ZWQgZnJvbSB0aG9zZSBzb3VjZXMgd2lsbCBub3QgYmUKZ3JvdXBlZC4KCjExLiBGb3IgZ3JvdXBpbmcgdGhlIHRlcm1zIGJhc2VkIG9uIHRoZSBrYXBwYSBzY29yZSwgaXQgaXMgbmVjZXNzYXJ5IHRvIHNldCB0aGUgc2l6ZSBvZiB0aGUgaW5pdGlhbCBncm91cAooZS5nLiAzKSBhbmQgdGhlIHBlcmNlbnRhZ2UgKG92ZXJsYXBpbmcgdGVybXMvZ3JvdXApIGZvciBncm91cCBtZXJnZSAoZS5nLiA1MCBwZXJjZW50KS4gRm9yIG1vcmUKZGV0YWlscyBzZWUgWzRdLiBBbGwgdGhlIHBvc3NpYmxlIGluaXRpYWwgZ3JvdXBzIHdpdGggdGhlIHRlcm1zIHNob3dpbmcgYSBrYXBwYSBzY29yZSBlcXVhbCBvcgphYm92ZSB0aGUgcHJlZGVmaW5lZCB0aHJlc2hvbGQgKGUuZy7CoT0gMC4zKSBhcmUgY3JlYXRlZC4gRnVydGhlciwgdGhlIGluaXRpYWwgZ3JvdXBzIGFyZSBpdGVycmF0aXZlbHkKY29tcGFyZWQgYW5kIG1lcmdlZCBpZiB0aGV5IGFyZSBvdmVybGFwcGluZyBpbiB0aGUgZGVmaW5lZCBwZXJjZW50YWdlLiBBIHRlcm0gY2FuIGJlIHBhcnQgb2YKc2V2ZXJhbCBncm91cHMuIFRoZSByZW9jdXJyZW5jZSBvZiB0aGUgdGVybSBpcyBzaG93biBieSBhZGRpbmcg4oCdIG7igJ0uIElmIHRoZSB0ZXJtcyBoYXZlIHZlcnkKc2ltaWxhciBhc3NvY2lhdGVkIGdlbmVzLCBpdCBpcyBwb3NzaWJsZSB0aGF0IHRoZSBpdGVyYXRpdmUgbWVyZ2luZyBvZiB0aGUgY3JlYXRlZCBncm91cHMgdG8gdGFrZSBhCmxvbmdlciB0aW1lIGluIHRoZSBhdHRlbXB0IG9mIG1lcmdpbmcgYWxsIHRoZSBncm91cHMuIEluIHRoaXMgY2FzZSwgaXQgaXMgcmVjb21tbmVuZGVkIHRvIGluY3JlYXNlCnRoZSBrYXBwYSBzY29yZSBsZXZlbCBvciB0byBpbmNyZWFzZSB0aGUgcGVyY2VudGFnZSBmb3IgZ3JvdXAgbWVyZ2UuCgojIyBBZHZhbmNlZCBTdGF0aXN0aWNhbCBPcHRpb25zCjEuIFNlbGVjdCBtaWQtUC12YWx1ZSBmb3IgYSBsZXNzIGNvbnNlcnZhdGl2ZSBoeXBlcmdlb21ldHJpYyB0ZXN0LgoyLiBTZWxlY3QgRG91YmxpbmcgZm9yIGEgbGVzcyBjb25zZXJ2YXRpdmUgdHdvIHRhaWxlZCBoeXBlcmdlb21ldHJpYyB0ZXN0LgoKIVtdKGltYWdlcy9DbHVlR08tQWR2YW5jZWRTdGF0aXN0aWNhbC5wbmcpCgoKIyMgQ2x1c3RlciBDb21wYXJpc29uCgpPbmNlIHNlbGVjdGVkIHRoZSBvcHRpb246ICoq4oCdQ29tcGFyZSBjbHVzdGVyc+KAnSoqLCB0d28gZmlsZSBjaG9vc2VycyBhcmUgbWFkZSBhdmFpbGFibGUuIFRoZSBzZWxlY3Rpb24gb2YgdGhlCm9udG9sb2d5IHRlcm1zIGlzIGZvbGxvd2luZyB0aGUgc2FtZSBzdGVwcyBhcyBpbiB0aGUgYW5hbHlzaXMgZm9yIGEgc2luZ2xlIGNsdXN0ZXIuCgpUaGUgZGlmZmVyZW5jZSByZWZlcnMgdG8gdGhlIG51bWJlciBhbmQgdGhlIHBlcmNlbnRhZ2Ugb2YgdGhlIGdlbmVzIHBlciB0ZXJtLiBUaG9zZSBzZWxlY3Rpb24gY3JpdGVyaWEgY2FuCmJlIGZsZXhpYmxlOiBDbHVzdGVyMSBPUiBDbHVzdGVyMiBvcHRpb25zICgxKSBvciBhcHBsaWVkIHN0cmljdGx5IGZvciBib3RoIGNsdXN0ZXJzOiBDbHVzdGVyMSBBTkQgQ2x1c3RlcjIKb3B0aW9ucyAoMikuIAoKSXQgaXMgcmVjb21tZW5kZWQgdG8gaGF2ZSBjb21wYXJhYmxlIG51bWJlciBvZiBpZGVudGlmaWVycyBpbiB0aGUgYW5hbHlzZWQgY2x1c3RlcnMuIElmIG9uZQpjbHVzdGVyIGlzIG11Y2ggbGFyZ2VyLCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhIHNob3VsZCBiZSBhcHBsaWVkIG1vcmUgc3RyaWN0bHkgKGUuZy4gaW5jcmVhc2UgdGhlIG51bWJlciBvZgpnZW5lcyBwZXIgdGVybSkuCgoKIVtdKGltYWdlcy9DbHVlR08tQ29tcGFyaXNvbi5wbmcpCgohW10oaW1hZ2VzL0NsdWVHby1Db21tb25UZXJtcy5wbmcpCgoKRnVydGhlciwgd2UgYW5hbHl6ZSB0aGUgdGVybXMgdHJvdWdoIHRoZSBwZXJzcGVjdGl2ZSBvZiB0aGVpciBhc3NvY2lhdGVkIGdlbmVzLiBJdCBpcyBwb3NzaWJsZSB0aGF0CmdlbmVzIGZyb20gYm90aCBjbHVzdGVycyB3aWxsIGJlIGFzc29jaWF0ZWQgd2l0aCBhIHRlcm0sIGJ1dCBpbiBkaWZmZXJlbnQgcHJvcG9ydGlvbnMuIFdlIGRlZmluZWQgYSB0ZXJtCmFzIHNwZWNpZmljIGZvciBvbmUgb2YgdGhlIGNsdXN0ZXJzIGlmIHRoZSBwZXJjZW50YWdlIG9mIGFzc29jaWF0ZWQgZ2VuZXMgZnJvbSB0aGlzIGNsdXN0ZXIgaXMgaGlnaGVyIHRoYW4KdGhlIHNlbGVjdGVkIHRocmVzaG9sZCAoZS5nLiA2NiBwZXJjZW50KSAoMykuIEFzIHJlc3VsdCwgY2hhcnRzIHdpdGggc3BlY2lmaWMgdGVybXMgZm9yIGVhY2ggY2x1c3RlciBhcmUKcHJvdmlkZWQuIFRoZSBjb21tb24gdGVybXMgYXJlIGluY2x1ZGVkIGluIGEgc2VwYXJhdGUgY2hhcnQuCgpPbiB0aGUgbmV0d29yaywgdGhlIGRpZmZlcmVudCBwcm9wb3J0aW9uIG9mIHRoZSBnZW5lcyBmcm9tIHRoZSBhbmFseXplZCBjbHVzdGVycyBpcyByZXByZXNlbnRlZCB3aXRoCmEgY29sb3IgZ3JhZGllbnQgZnJvbSBncmVlbiwgZm9yIHRoZSBmaXJzdCBjbHVzdGVyIGdlbmVzLCB0byByZWQgZm9yIHRoZSBzZWNvbmQgY2x1c3Rlci4KVGhlIHZpc3VhbGl6YXRpb24gb2YgdGhlIGdyb3VwcyBvbiB0aGUgbmV0d29yayBjYW4gYmUgc3dpdGNoZWQgd2l0aCB0aGUgb25lIG9mIHRoZSB1cGxvYWRlZCBjbHVzdGVycwpkaXN0cmlidXRpb24gb24gdGhlIHNlbGVjdGVkIHRlcm1zIChzZWUgRmlndXJlIGJlbG93KS4KCgohW10oaW1hZ2VzL0NsdWVHTy1JbnRlZ3JhdGVkLnBuZykKCiMjIENsdWVHTyByZXN1bHQgdmlzdWFsaXphdGlvbnMKCiFbXShpbWFnZXMvQ2x1ZUdPLVJlc3VsdF9WaXMucG5nKQoKCgoKIyMgSW5jbHVkZSB5b3VyIG9yZ2FuaXNtIG9mIGludGVyZXN0IGluIENsdWVHTwoKQ2x1ZUdPIGFsbG93cyB0byBhZGQgbmV3IG9yZ2FuaXNtcywgbm90IGluY2x1ZGVkIGluIG91ciBpbml0aWFsIHNlbGVjdGlvbi4KRm9yIGVhY2ggbmV3IG9yZ2FuaXNtLCBhIGtleUlkZW50aWZpZXIgZmlsZTogb3JnYW5pc20uZ2VuZTJhY2Nlc3Npb24udHh0IChlLmcuIE9yeXphIFNhdGl2YS5nZW5lMmFjY2Vzc2lvbikKaGFzIHRvIGJlIGNyZWF0ZWQuIEluIHRoaXMgZmlsZSwgdGhlIGZpcnN0IGNvbHVtbiAo4oCdVW5pcXVlSUQjRW50cmV6R2VuZUlE4oCdKSB3aWxsIGNvbnRhaW4gdGhlIGtleUlEIChlLmcuCkVudHJlekdlbmVJRCkgdGhhdCBpcyB1c2VkIGZvciBtYXBwaW5nLiBOZXh0IGNvbHVtbiwg4oCdU3ltYm9sSUTigJ0gY29udGFpbnMgdGhlIG9mZmljaWFsIGdlbmUgc3ltYm9sCm9yIG9mZmljaWFsIHN5bWJvbCBhbmQgc3lub255bXMgc2VwYXJhdGVkIGJ5IOKAnXzigJ0uIE90aGVyIHR5cGVzIG9mIGlkZW50aWZpZXJzIGNhbiBiZSBpbmNsdWRlZCBpbiB0aGUgbmV4dApjb2x1bW5zLgoKVGhlIHNlY29uZCBmaWxlIG5lZWRlZCBpcyBvcmdhbmlzbS5wcm9wZXJ0aWVzIChlLmcuIE9yeXphIFNhdGl2YS5wcm9wZXJ0aWVzKS4gVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSBvcmdhbmlzbSBuYW1lLCB0aGUga2VnZ0lELCB0aGUgdXJsIG9mIHRoZSBHTyBhc3NvY2lhdGlvbiBmaWxlLCB0aGUgdGF4b25vbXkgaWQuIFRoZSBzYW1lIHVybCBjYW4gYmUgdXNlZCBmb3Igb3RoZXIgb3JnYW5pc21zIGFmdGVyIGNoYW5naW5nIHRoZSBuYW1lIG9mIHRoZSBhbm5vdGF0aW9uIGZpbGUuIEluIG1vc3Qgb2YgdGhlIGNhc2VzLCB0aGVyZSBhcmUgbm8Kc3BlY2lhbCBmaWxlcyByZXF1aXJlZCBmb3IgdGhlIHVwZGF0ZSAoZmFsc2UpLgpIZXJlIGlzIHRoZSBjb250ZW50IG9mIHRoZSAucHJvcGVydGllcyBmaWxlIGZvciBPcnl6YSBzYXRpdmE6Cm9yZ2FuaXNtLm5hbWUgPSBPcnl6YSBzYXRpdmEKb3JnYW5pc20ua2VnZy5uYW1lID0gb3NhCm9yZ2FuaXNtLmdvLnVybCA9IGZ0cDovL2Fub255bW91czphbm9ueW1vdXNAZnRwLmdlbmVvbnRvbG9neS5vcmcvcHViL2dvL2dlbmUtYXNzb2NpYXRpb25zL2dlbmUKYXNzb2NpYXRpb24uZ3JhbWVuZSBvcnl6YS5negpvcmdhbmlzbS50YXhpZCA9IDM5OTQ2Cm9yZ2FuaXNtLnVwZGF0ZS5uZWVkcy5zcGVjaWFsLmZpbGUgPSBmYWxzZQpUaG9zZSBmaWxlcyBoYXZlIHRvIGJlIGFkZGVkIGluIGEgbmV3IGZvbGRlciAoZS5nLiBPcmdhbmlzbSBPcnl6YSBzYXRpdmEpIGNyZWF0ZWQgaW4gVXNlckhvbWVGb2xkZXIsCi5jbHVlZ29wbHVnaW4sIGN1cnJlbnRWZXJzaW9uLCBDbHVlR09GaWxlcywgQ2x1ZUdPU291cmNlRmlsZXMuClJlbWFyazogQXQgdGhlIGFkZGl0aW9uIG9mIGEgbmV3IG9yZ2FuaXNtLCBtYWtlIHN1cmUgdGhhdCB0aGUgaWRzIHByb3ZpZGVkIGJ5IEtFR0cgYXJlIHRoZSBzYW1lIGFzCnRoZSBVbmlxdWVJRHMgZnJvbSBvcmdhbmlzbS5nZW5lMmFjY2Vzc2lvbi50eHQuCgoKPGRpdiBjbGFzcz0iZXhlcmNpc2UiPgoKIyBXYWxrLXRocm91Z2ggZXhhbXBsZQoKIyMgQ2x1ZUdPIHNldHRpbmdzCgoqIHNldCB0aGUgdHlwZSBvZiBhbmFseXNpczogQ29tcGFyZSBDbHVzdGVyCiogc2VsZWN0IHRoZSBvcmdhbmlzbTogSG9tbyBTYXBpZW5zIGFuZCB0aGUgdGhlIHR5cGUgb2YgaWRzIHVzZWQ6IEFjY2Vzc2lvbklECiogbG9hZCBzYW1wbGUgZ2VuZSBsaXN0czoKICAqIGNob29zZSBDbHVzdGVyICMxOiBzZWxlY3QgR1NFNjg4NyBOS2NlbGwgSGVhbHRoeSB0b3AyMDBVcFJlZ3VsYXRlZC50eHQKICAqIGNob29zZSBDbHVzdGVyICMyOiBHU0U2ODg3IE5LY2VsbCBIZWFsdGh5IHRvcDIwMERvd25SZWd1bGF0ZWQudHh0Ciogc2VsZWN0IHRoZSBPbnRvbG9naWVzOgogICogR08gQmlvbG9naWNhbFByb2Nlc3MgMTAuMTAuMjAwOCAoQWxsIEV2aWRlbmNlIGNvZGVzKSwKICAqIEtFR0cgUGF0aHdheXMgMTQuMTAuMjAwOCBhbmQKICAqIEJpb0NhcnRhIHBhdGh3YXkgcmVhY3RvbWUgMjAuMTAuMjAwOAoqIHNlbGVjdCB0aGUgc3RhdGlzdGljYWwgdGVzdDogRW5yaWNobWVudC9EZXBsZWN0aW9uIChUd28gc2lkZWQgaHlwZXJnZW9tZXRyaWMgdGVzdCksIEZpc2hlckV4YWN0VGVzdAoqIHNlbGVjdCB0aGUgY29ycmVjdGlvbiBtZXRob2Q6IEJvbmZlcnJvbmkKKiBjbGljayBTaG93IEFkdmFuY2VkIFNldHRpbmdzCiogc2V0IEdPIFRyZWUgTGV2ZWw6IE1pbiA0IGFuZCBNYXggNQoqIHNldCB0aGUgc2VsZWN0aW9uIGNyaXRlcmlhIGZvciB0aGUgdGVybXMgdGhhdCBoYXZlIGFzc29jaWF0ZWQgZ2VuZXMgZnJvbSBjbHVzdGVyIDE6IG1pbiAyIGdlbmVzL3Rlcm0KYW5kIG1pbmltdW0gNCUgZnJvbSBhbGwgdGhlIEdlbmVzIGFzc29jaWF0ZWQgd2l0aCB0aGUgdGVybQoqIHNlbGVjdCBPUiAoZS5nLiBtaW4gMiBnZW5lcyBmcm9tIGNsdXN0ZXIgIzEgb3IgbWluIDIgZ2VuZXMgZnJvbSBjbHVzdGVyICMyKQoqIHNldCBpcyBzcGVjaWZpYyB0byA2NiUgKGlmIDY2JSBvciB0aGUgZ2VuZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSB0ZXJtIGFyZSBmcm9tIGNsdXN0ZXIgIzEsIHRoZSB0ZXJtCmlzIGNvbnNpZGVyZWQgc3BlY2lmaWMgZm9yIHRoaXMgY2x1c3RlcikKKiBzZXQgdGhlIHNlbGVjdGlvbiBjcml0ZXJpYSBmb3IgdGhlIHRlcm1zIHRoYXQgaGF2ZSBhc3NvY2lhdGVkIGdlbmVzIGZyb20gY2x1c3RlciAyOiBtaW4gMiBnZW5lcy90ZXJtCmFuZCBtaW5pbXVtIDQlIGZyb20gYWxsIHRoZSBHZW5lcyBhc3NvY2lhdGVkIHdpdGggdGhlIHRlcm0KKiBzZWxlY3QgVXNlIEdPIFRlcm0gR3JvdXBpbmcKKiBzZWxlY3QgRml4IEdyb3VwIGNvbG9yaW5nCiogc2VsZWN0IExlYWRpbmcgR3JvdXAgVGVybSBiYXNlZCBvbiBIaWdoZXN0IFNpZ25pZmljYW5jZQoqIHNlbGVjdCBLYXBwYSBTY29yZSBncm91cGluZyB3aXRoIDMgdGVybXMgaW4gaW5pdGlhbCBncm91cCBhbmQgNTAlIG92ZXJsYXAgZm9yIGdyb3VwcyB0byBtZXJnZQoqIHNlbGVjdCBTaG93RGlmZmVyZW5jZQoqIFN0YXJ0CgohW10oaW1hZ2VzL0NsdWVHTy1GaWd1cmUucG5nKQoKCiMjIEN1c3RvbWl6ZSB0aGUgbmV0d29yayB1c2luZyBDeXRvc2NhcGUgZmVhdHVyZXMKCiogc2VsZWN0IFdpek1hcHBlciAoQ3l0b3NjYXBlIENvbnRyb2wgUGFuZWwpCiogc2VsZWN0IE5vZGUgRm9udCBTaXplCiogc2V0IHRoZSB2YWx1ZSBvZiBGQUxTRSAoc2l6ZSBmb3IgdGhlIG5hbWUgb2YgdGhlIHRlcm1zKSB0byAwLjAwMSBhbmQgcHJlc3MgRW50ZXIKKiBzZXQgdGhlIHZhbHVlIG9mIFRSVUUgKHNpemUgZm9yIHRoZSBuYW1lIG9mIGdyb3VwcykgdG8gMjYgYW5kIHByZXNzIEVudGVyCiogc2VsZWN0IExheW91dCAoQ3l0b3NjYXBlIG1lbnUgYmFyKQoqIHNldCBzY2FsZSB0byAxLzMKKiB6b29tIHRoZSBpbWFnZQoqIGNoYW5nZSB0aGUgcG9zaXRpb24gb2YgdGhlIGxlYWRpbmcgdGVybXMgdG8gbWFrZSB2aXNpYmxlIHRoZSBuYW1lIG9mIHRoZSBncm91cAoqIGNoYW5nZSB0aGUgcG9zc2l0aW9uIG9mIG5vdGdyb3VwZWQgdGVybXMgaWYgZHVlIHRvIHJlc2NhbGluZyB0aGV5IGFyZSB0b28gY2xvc2UgdG8gYSBncm91cAoqIGZvciB2aXN1YWxpemluZyBncm91cHMgcHJlc3MgU2hvdyBHcm91cHMKCiFbXShpbWFnZXMvQ2x1ZUdPLUN1c3RvbWl6ZWRGaWd1cmUucG5nKQoKIVtdKGltYWdlcy9DbHVlR08tQ3VzdG9taXplZFNldHRpbmcucG5nKQoKPC9kaXY+Cgo8YnI+PC9icj4KCg==